//你好
const def = String.raw/* cpp */`

#define _LIBC
#include <stdio.h>
//#include <stdlib.h>
#include <string.h>

#include "lib/system.h"

#include "lib/ArrayList.h"
//#include "lib/FileSystem.h"
#include "lib/StorageDevice.h"
#include "lib/Sd2Card.h"
#include "lib/ch375b.h"
#include "lib/3d.h"

#include "fs/ff.h"			/* Basic definitions and declarations of API */
#include "fs/diskio.h"		/* Declarations of MAI */

#include "quickjs/list.h"
#include "quickjs/cutils.h"
#include "quickjs/quickjs.h"

#include "tjpg/tjpg1.h"

#include "lib/tlsf.h"


#define CHAR_TABLE 0x00000010
#define HZK 0x00001020
#define U2GB 0x00042590

int* char_table;
int* gb_char_table;
int* u2gb;

JSRuntime *rt;
JSContext *ctx;
JSValue global;

static JSClassID js_windows_class_id;
static JSClassID js_window_class_id;
static JSClassID js_button_class_id;
static JSClassID js_form_class_id;
static JSClassID js_label_class_id;
static JSClassID js_input_class_id;

static JSClassID js_stream_class_id;

static JSClassID js_image_class_id;

static JSClassID js_canvas3d_class_id;
static JSClassID js_object3d_class_id;


//root : Dir {name:string, type: 1 }
//dir.dir() => File/Dir[]

//File: {name:string, size:number, type: 0 }
//file.open(r/w) => Stream

//Stream :
//stream.read() => byte
//stream.read(buffer) => void























class Window;

class Button;

`;

const base = String.raw/* cpp */`
  #include "lib/key.h"
  const unsigned char cursor[] = {
  0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xa6, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };

  int loadCur(){
    short* cursorData = (short*)cursor;
    for(int j=0;j<32;j++){
      for(int i=0;i<32;i++){
        // volatile int* p = (int*)(VGA_CUR_PIX+((i+j*32)<<2));
        // *p=0xFFFF;
        // *p=0xFFFF;
        // //*p=cursorData[i+j*32];
        IOWR(VGA_CUR_PIX, (i+j*32), cursorData[i+j*32]);
        //IOWR(VGA_CUR_PIX, (i+j*32), cursorData[i+j*32]);
      }
    }
  }

  const unsigned char key2char[] = {
  '\0','\0',////                          0x00
  '\0','\0',//#define KEY_F9              0x01
  '\0','\0',////                          0x02
  '\0','\0',//#define KEY_F5              0x03
  '\0','\0',//#define KEY_F3              0x04
  '\0','\0',//#define KEY_F1              0x05
  '\0','\0',//#define KEY_F2              0x06
  '\0','\0',//#define KEY_F12             0x07
  '\0','\0',////                          0x08
  '\0','\0',//#define KEY_F10             0x09
  '\0','\0',//#define KEY_F8              0x0A
  '\0','\0',//#define KEY_F6              0x0B
  '\0','\0',//#define KEY_F4              0x0C
  '\t','\t',//#define KEY_TAB             0x0D
  '\u0060', '~',//#define KEY_TILDE           0x0E //~ \`
  '\0','\0',////                          0x0F
  '\0','\0',////                          0x10
  '\0','\0',//#define KEY_ALTL            0x11
  '\0','\0',//#define KEY_SHIFTL          0x12
  '\0','\0',////                          0x13
  '\0','\0',//#define KEY_CTRLL           0x14
  'q', 'Q',//#define KEY_Q               0x15
  '1', '!',//#define KEY_1               0x16
  '\0','\0',////                          0x17
  '\0','\0',////                          0x18
  '\0','\0',////                          0x19
  'z', 'Z',//#define KEY_Z               0x1A
  's', 'S',//#define KEY_S               0x1B
  'a', 'A',//#define KEY_A               0x1C
  'w', 'W',//#define KEY_W               0x1D
  '2', '@',//#define KEY_2               0x1E
  '\0','\0',////                          0x1F
  '\0','\0',////                          0x20
  'c', 'C',//#define KEY_C               0x21
  'x', 'X',//#define KEY_X               0x22
  'd', 'D',//#define KEY_D               0x23
  'e', 'E',//#define KEY_E               0x24
  '4', '$',//#define KEY_4               0x25
  '3', '#',//#define KEY_3               0x26
  '\0','\0',////                          0x27
  '\0','\0',////                          0x28
  ' ', ' ',//#define KEY_SPACE           0x29
  'v', 'V',//#define KEY_V               0x2A
  'f', 'F',//#define KEY_F               0x2B
  't', 'T',//#define KEY_T               0x2C
  'r', 'R',//#define KEY_R               0x2D
  '5', '%',//#define KEY_5               0x2E
  '\0','\0',////                          0x2F
  '\0','\0',////                          0x30
  'n', 'N',//#define KEY_N               0x31
  'b', 'B',//#define KEY_B               0x32
  'h', 'H',//#define KEY_H               0x33
  'g', 'G',//#define KEY_G               0x34
  'y', 'Y',//#define KEY_Y               0x35
  '6', '^',//#define KEY_6               0x36
  '\0','\0',////                          0x37
  '\0','\0',////                          0x38
  '\0','\0',////                          0x39
  'm', 'M',//#define KEY_M               0x3A
  'j', 'J',//#define KEY_J               0x3B
  'u', 'U',//#define KEY_U               0x3C
  '7', '&',//#define KEY_7               0x3D
  '8', '*',//#define KEY_8               0x3E
  '\0','\0',////                          0x3F
  '\0','\0',////                          0x40
  ',', '<',//#define KEY_COMMA           0x41 // ,
  'k', 'K',//#define KEY_K               0x42
  'i', 'I',//#define KEY_I               0x43
  'o', 'O',//#define KEY_O               0x44
  '0', ')',//#define KEY_0               0x45
  '9', '(',//#define KEY_9               0x46
  '\0','\0',////                          0x47
  '\0','\0',////                          0x48
  '.', '>',//#define KEY_PERIOD          0x49 // .
  '/', '?',//#define KEY_QUESTION        0x4A // ? /
  'l', 'L',//#define KEY_L               0x4B
  ';', ':',//#define KEY_SEMICOLN        0x4C // ;
  'p', 'P',//#define KEY_P               0x4D
  '-', '_',//#define KEY_MINUS           0x4E //-
  '\0','\0',////                          0x4F
  '\0','\0',////                          0x50
  '\0','\0',////                          0x51
  '\'','\"',//#define KEY_QUOTES          0x52 // '
  '\0','\0',////                          0x53
  '[', '{',//#define KEY_BRACKETL        0x54 // [
  '=', '+',//#define KEY_PLUS            0x55 //+ =
  '\0','\0',////                          0x56
  '\0','\0',////                          0x57
  '\0','\0',//#define KEY_CAPSLOCK        0x58
  '\0','\0',//#define KEY_SHIFTR          0x59
  '\n','\n',//#define KEY_ENTER           0x5A
  ']', '}',//#define KEY_BRACKETR        0x5B // ]
  '\0','\0',////                          0x5C
  '\\', '|',//#define KEY_PIPE            0x5D // | \ //
  '\0','\0',////                          0x5E
  '\0','\0',////                          0x5F
  '\0','\0',////                          0x60
  '\0','\0',////                          0x61
  '\0','\0',////                          0x62
  '\0','\0',////                          0x63
  '\0','\0',////                          0x64
  '\0','\0',////                          0x65
  '\0','\0',////0x08,0x08,//#define KEY_BKSP            0x66  0000 1000 010 8 0x08 BS (backspace) ??
  '\0','\0',////                          0x67
  '\0','\0',////                          0x68
  '1', '1',//#define KEY_NUMPAD_1        0x69//(F069)
  '\0','\0',////                          0x6A
  '4', '4',//#define KEY_NUMPAD_4        0x6B//(F06B)
  '7', '7',//#define KEY_NUMPAD_7        0x6C//(F06C)
  '\0','\0',////                          0x6D
  '\0','\0',////                          0x6E
  '\0','\0',////                          0x6F
  '0', '0',//#define KEY_NUMPAD_0        0x70//(F070)
  '.', '.',//#define KEY_NUMPAD_DOT      0x71//(F071)//.
  '2', '2',//#define KEY_NUMPAD_2        0x72//(F072)
  '5', '5',//#define KEY_NUMPAD_5        0x73//(F073)
  '6', '6',//#define KEY_NUMPAD_6        0x74//(F074)
  '8', '8',//#define KEY_NUMPAD_8        0x75//(F075)
  '\0','\0',//#define KEY_ESC             0x76
  '\0','\0',//#define KEY_NUMPAD_NUM_LOCK 0x77//(F077)
  '\0','\0',//#define KEY_F11             0x78
  '+', '+',//#define KEY_NUMPAD_PLUS     0x79//(F079)//+
  '3', '3',//#define KEY_NUMPAD_3        0x7A//(F07A)
  '-', '-',//#define KEY_NUMPAD_MIN      0x7B//(F07B)//-
  '*', '*',//#define KEY_NUMPAD_MUL      0x7C//(F07C)//*
  '9', '9',//#define KEY_NUMPAD_9        0x7D//(F07D)
  '\0','\0',//#define KEY_SCROLL_LOCK     0x7E//(F07E)
  '\0','\0',////                          0x7F
  '\0','\0',////                          0x80
  '\0','\0',////                          0x81
  '\0','\0',////                          0x82
  '\0','\0',//#define KEY_F7              0x83
  '\0','\0',////                          0x84
  '\0','\0',////                          0x85
  '\0','\0',////                          0x86
  '\0','\0',////                          0x87
  '\0','\0',////                          0x88
  '\0','\0',////                          0x89
  '\0','\0',////                          0x8A
  '\0','\0',////                          0x8B
  '\0','\0',////                          0x8C
  '\0','\0',////                          0x8D
  '\0','\0',////                          0x8E
  '\0','\0',////                          0x8F
  '\0','\0',////                          (0x10|0x80)
  '\0','\0',//#define KEY_ALTR            (0x11|0x80) //E011 (E0F011)
  '\0','\0',////                          (0x12|0x80)
  '\0','\0',////                          (0x13|0x80)
  '\0','\0',//#define KEY_CTRLR           (0x14|0x80) //E014 (E0F014)
  '\0','\0',////                          (0x15|0x80)
  '\0','\0',////                          (0x16|0x80)
  '\0','\0',////                          (0x17|0x80)
  '\0','\0',////                          (0x18|0x80)
  '\0','\0',////                          (0x19|0x80)
  '\0','\0',////                          (0x1A|0x80)
  '\0','\0',////                          (0x1B|0x80)
  '\0','\0',////                          (0x1C|0x80)
  '\0','\0',////                          (0x1D|0x80)
  '\0','\0',////                          (0x1E|0x80)
  '\0','\0',//#define KEY_WINL            (0x1F|0x80) //E01F (E0F01F)
  '\0','\0',////                          (0x20|0x80)
  '\0','\0',////                          (0x21|0x80)
  '\0','\0',////                          (0x22|0x80)
  '\0','\0',////                          (0x23|0x80)
  '\0','\0',////                          (0x24|0x80)
  '\0','\0',////                          (0x25|0x80)
  '\0','\0',////                          (0x26|0x80)
  '\0','\0',//#define KEY_WINR            (0x27|0x80) //E027 (E0F027)
  '\0','\0',////                          (0x28|0x80)
  '\0','\0',////                          (0x29|0x80)
  '\0','\0',////                          (0x2A|0x80)
  '\0','\0',////                          (0x2B|0x80)
  '\0','\0',////                          (0x2C|0x80)
  '\0','\0',////                          (0x2D|0x80)
  '\0','\0',////                          (0x2E|0x80)
  '\0','\0',//#define KEY_MENU            (0x2F|0x80) //E02F (E0F02F)
  '\0','\0',////                          (0x40|0x80)
  '\0','\0',////                          (0x41|0x80)
  '\0','\0',////                          (0x42|0x80)
  '\0','\0',////                          (0x43|0x80)
  '\0','\0',////                          (0x44|0x80)
  '\0','\0',////                          (0x45|0x80)
  '\0','\0',////                          (0x46|0x80)
  '\0','\0',////                          (0x47|0x80)
  '\0','\0',////                          (0x48|0x80)
  '\0','\0',////                          (0x49|0x80)
  '/', '/',//#define KEY_NUMPAD_DIV      (0x4A|0x80) //E04A (E0F04A) // /
  '\0','\0',////                          (0x4B|0x80)
  '\0','\0',////                          (0x4C|0x80)
  '\0','\0',////                          (0x4D|0x80)
  '\0','\0',////                          (0x4E|0x80)
  '\0','\0',////                          (0x4F|0x80)
  '\0','\0',////                          (0x50|0x80)
  '\0','\0',////                          (0x51|0x80)
  '\0','\0',////                          (0x52|0x80)
  '\0','\0',////                          (0x53|0x80)
  '\0','\0',////                          (0x54|0x80)
  '\0','\0',////                          (0x55|0x80)
  '\0','\0',////                          (0x56|0x80)
  '\0','\0',////                          (0x57|0x80)
  '\0','\0',////                          (0x58|0x80)
  '\0','\0',////                          (0x59|0x80)
  '\n','\n',//#define KEY_NUMPAD_ENTER    (0x5A|0x80) //E05A (E0F05A)
  '\0','\0',////                          (0x5B|0x80)
  '\0','\0',////                          (0x5C|0x80)
  '\0','\0',////                          (0x5D|0x80)
  '\0','\0',////                          (0x5E|0x80)
  '\0','\0',////                          (0x5F|0x80)
  '\0','\0',////                          (0x60|0x80)
  '\0','\0',////                          (0x61|0x80)
  '\0','\0',////                          (0x62|0x80)
  '\0','\0',////                          (0x63|0x80)
  '\0','\0',////                          (0x64|0x80)
  '\0','\0',////                          (0x65|0x80)
  '\0','\0',////                          (0x66|0x80)
  '\0','\0',////                          (0x67|0x80)
  '\0','\0',////                          (0x68|0x80)
  '\0','\0',//#define KEY_END             (0x69|0x80) //E069 (E0F069)
  '\0','\0',////                          (0x6A|0x80)
  0x13,0x13,//#define KEY_ARROW_LEFT      (0x6B|0x80) //E06B (E0F06B) 0001 0011 023 19 0x13 DC3 (device control 3) ????3
  '\0','\0',//#define KEY_HOME            (0x6C|0x80) //E06C (E0F06C)
  '\0','\0',////                          (0x6D|0x80)
  '\0','\0',////                          (0x6E|0x80)
  '\0','\0',////                          (0x6F|0x80)
  '\0','\0',//#define KEY_INSERT          (0x70|0x80) //E070 (E0F070)
  '\0','\0',//#define KEY_DELETE          (0x71|0x80) //E071 (E0F071)
  0x12,0x12,//#define KEY_ARROW_DOWN      (0x72|0x80) //E072 (E0F072) 0001 0010 022 18 0x12 DC2 (device control 2) ????2
  '\0','\0',////                          (0x73|0x80)
  0x14,0x14,//#define KEY_ARROW_RIGHT     (0x74|0x80) //E074 (E0F074) 0001 0100 024 20 0x14 DC4 (device control 4) ????4
  0x11,0x11,//#define KEY_ARROW_UP        (0x75|0x80) //E075 (E0F075) 0001 0001 021 17 0x11 DC1 (device control 1) ????1
  '\0','\0',////                          (0x76|0x80)
  '\0','\0',////                          (0x77|0x80)
  '\0','\0',////                          (0x78|0x80)
  '\0','\0',////                          (0x79|0x80)
  '\0','\0',//#define KEY_PAGE_DOWN       (0x7A|0x80) //E07A (E0F07A)
  '\0','\0',//#define KEY_PAGE_UP         (0x7D|0x80) //E07D (E0F07D)
  '\0','\0',////                          (0x7E|0x80)
  '\0','\0',////                          (0x7F|0x80)
  };

  const unsigned char usb2ps2[] = {
  //Usage ID Usage Name Usage Type AT-101 PC-AT Mac Unix Boot
  0                   ,//00 Reserved
  0                   ,//01 Keyboard ErrorRollOver1 Sel N/A 3 3 3 4/101/104
  0                   ,//02 Keyboard POSTFail1 Sel N/A 3 3 3 4/101/104
  0                   ,//03 Keyboard ErrorUndefined1 Sel N/A 3 3 3 4/101/104
  KEY_A               ,//04 Keyboard a and A2 Sel 31 3 3 3 4/101/104
  KEY_B               ,//05 Keyboard b and B Sel 50 3 3 3 4/101/104
  KEY_C               ,//06 Keyboard c and C2 Sel 48 3 3 3 4/101/104
  KEY_D               ,//07 Keyboard d and D Sel 33 3 3 3 4/101/104
  KEY_E               ,//08 Keyboard e and E Sel 19 3 3 3 4/101/104
  KEY_F               ,//09 Keyboard f and F Sel 34 3 3 3 4/101/104
  KEY_G               ,//0A Keyboard g and G Sel 35 3 3 3 4/101/104
  KEY_H               ,//0B Keyboard h and H Sel 36 3 3 3 4/101/104
  KEY_I               ,//0C Keyboard i and I Sel 24 3 3 3 4/101/104
  KEY_J               ,//0D Keyboard j and J Sel 37 3 3 3 4/101/104
  KEY_K               ,//0E Keyboard k and K Sel 38 3 3 3 4/101/104
  KEY_L               ,//0F Keyboard l and L Sel 39 3 3 3 4/101/104
  KEY_M               ,//10 Keyboard m and M2 Sel 52 3 3 3 4/101/104
  KEY_N               ,//11 Keyboard n and N Sel 51 3 3 3 4/101/104
  KEY_O               ,//12 Keyboard o and O2 Sel 25 3 3 3 4/101/104
  KEY_P               ,//13 Keyboard p and P2 Sel 26 3 3 3 4/101/104
  KEY_Q               ,//14 Keyboard q and Q2 Sel 17 3 3 3 4/101/104
  KEY_R               ,//15 Keyboard r and R Sel 20 3 3 3 4/101/104
  KEY_S               ,//16 Keyboard s and S Sel 32 3 3 3 4/101/104
  KEY_T               ,//17 Keyboard t and T Sel 21 3 3 3 4/101/104
  KEY_U               ,//18 Keyboard u and U Sel 23 3 3 3 4/101/104
  KEY_V               ,//19 Keyboard v and V Sel 49 3 3 3 4/101/104
  KEY_W               ,//1A Keyboard w and W2 Sel 18 3 3 3 4/101/104
  KEY_X               ,//1B Keyboard x and X2 Sel 47 3 3 3 4/101/104
  KEY_Y               ,//1C Keyboard y and Y2 Sel 22 3 3 3 4/101/104
  KEY_Z               ,//1D Keyboard z and Z2 Sel 46 3 3 3 4/101/104
  KEY_1               ,//1E Keyboard 1 and !2 Sel 2 3 3 3 4/101/104
  KEY_2               ,//1F Keyboard 2 and @2 Sel 3 3 3 3 4/101/104
  KEY_3               ,//20 Keyboard 3 and #2 Sel 4 3 3 3 4/101/104
  KEY_4               ,//21 Keyboard 4 and $2 Sel 5 3 3 3 4/101/104
  KEY_5               ,//22 Keyboard 5 and %2 Sel 6 3 3 3 4/101/104
  KEY_6               ,//23 Keyboard 6 and ^2 Sel 7 3 3 3 4/101/104
  KEY_7               ,//24 Keyboard 7 and &2 Sel 8 3 3 3 4/101/104
  KEY_8               ,//25 Keyboard 8 and *2 Sel 9 3 3 3 4/101/104
  KEY_9               ,//26 Keyboard 9 and (2 Sel 10 3 3 3 4/101/104
  KEY_0               ,//27 Keyboard 0 and )2 Sel 11 3 3 3 4/101/104
  KEY_ENTER           ,//28 Keyboard Return (ENTER)3 Sel 43 3 3 3 4/101/104
  KEY_ESC             ,//29 Keyboard ESCAPE Sel 110 3 3 3 4/101/104
  KEY_BKSP            ,//2A Keyboard DELETE (Backspace)4 Sel 15 3 3 3 4/101/104
  KEY_TAB             ,//2B Keyboard Tab Sel 16 3 3 3 4/101/104
  KEY_SPACE           ,//2C Keyboard Spacebar Sel 61 3 3 3 4/101/104
  KEY_MINUS           ,//2D Keyboard - and (underscore)2 Sel 12 3 3 3 4/101/104
  KEY_PLUS            ,//2E Keyboard = and +2 Sel 13 3 3 3 4/101/104
  KEY_BRACKETL        ,//2F Keyboard [ and {2 Sel 27 3 3 3 4/101/104
  KEY_BRACKETR        ,//30 Keyboard ] and }2 Sel 28 3 3 3 4/101/104
  KEY_PIPE            ,//31 Keyboard \and | Sel 29 3 3 3 4/101/104
  0                   ,//32 Keyboard Non-US # and ?5 Sel 42 3 3 3 4/101/104
  KEY_SEMICOLN        ,//33 Keyboard ; and :2 Sel 40 3 3 3 4/101/104
  KEY_QUOTES          ,//34 Keyboard ??? and ???2 Sel 41 3 3 3 4/101/104
  KEY_TILDE           ,//35 Keyboard Grave Accent and Tilde2 Sel 1 3 3 3 4/101/104
  KEY_COMMA           ,//36 Keyboard , and <2 Sel 53 3 3 3 4/101/104
  KEY_PERIOD          ,//37 Keyboard . and >2 Sel 54 3 3 3 4/101/104
  KEY_QUESTION        ,//38 Keyboard / and ?2 Sel 55 3 3 3 4/101/104
  KEY_CAPSLOCK        ,//39 Keyboard Caps Lock6 Sel 30 3 3 3 4/101/104
  KEY_F1              ,//3A Keyboard F1 Sel 112 3 3 3 4/101/104
  KEY_F2              ,//3B Keyboard F2 Sel 113 3 3 3 4/101/104
  KEY_F3              ,//3C Keyboard F3 Sel 114 3 3 3 4/101/104
  KEY_F4              ,//3D Keyboard F4 Sel 115 3 3 3 4/101/104
  KEY_F5              ,//3E Keyboard F5 Sel 116 3 3 3 4/101/104
  KEY_F6              ,//3F Keyboard F6 Sel 117 3 3 3 4/101/104
  KEY_F7              ,//40 Keyboard F7 Sel 118 3 3 3 4/101/104
  KEY_F8              ,//41 Keyboard F8 Sel 119 3 3 3 4/101/104
  KEY_F9              ,//42 Keyboard F9 Sel 120 3 3 3 4/101/104
  KEY_F10             ,//43 Keyboard F10 Sel 121 3 3 3 4/101/104
  KEY_F11             ,//44 Keyboard F11 Sel 122 3 3 3 4/101/104
  KEY_F12             ,//45 Keyboard F12 Sel 123 3 3 3 4/101/104
  0                   ,//46 Keyboard PrintScreen7 Sel 124 3 3 3 4/101/104
  KEY_SCROLL_LOCK     ,//47 Keyboard Scroll Lock6 Sel 125 3 3 3 4/101/104
  0                   ,//48 Keyboard Pause7 Sel 126 3 3 3 4/101/104
  KEY_INSERT          ,//49 Keyboard Insert7 Sel 75 3 3 3 4/101/104
  KEY_HOME            ,//4A Keyboard Home7 Sel 80 3 3 3 4/101/104
  KEY_PAGE_UP         ,//4B Keyboard PageUp7 Sel 85 3 3 3 4/101/104
  KEY_DELETE          ,//4C Keyboard Delete Forward7,8 Sel 76 3 3 3 4/101/104
  KEY_END             ,//4D Keyboard End7 Sel 81 3 3 3 4/101/104
  KEY_PAGE_DOWN       ,//4E Keyboard PageDown7 Sel 86 3 3 3 4/101/104
  KEY_ARROW_RIGHT     ,//4F Keyboard RightArrow7 Sel 89 3 3 3 4/101/104
  KEY_ARROW_LEFT      ,//50 Keyboard LeftArrow7 Sel 79 3 3 3 4/101/104
  KEY_ARROW_DOWN      ,//51 Keyboard DownArrow7 Sel 84 3 3 3 4/101/104
  KEY_ARROW_UP        ,//52 Keyboard UpArrow7 Sel 83 3 3 3 4/101/104
  KEY_NUMPAD_NUM_LOCK ,//53 Keypad Num Lock and Clear6 Sel 90 3 3 3 4/101/104
  KEY_NUMPAD_DIV      ,//54 Keypad /7 Sel 95 3 3 3 4/101/104
  KEY_NUMPAD_MUL      ,//55 Keypad * Sel 100 3 3 3 4/101/104
  KEY_NUMPAD_MIN      ,//56 Keypad - Sel 105 3 3 3 4/101/104
  KEY_NUMPAD_PLUS     ,//57 Keypad + Sel 106 3 3 3 4/101/104
  KEY_NUMPAD_ENTER    ,//58 Keypad ENTER3 Sel 108 3 3 3 4/101/104
  KEY_NUMPAD_1        ,//59 Keypad 1 and End Sel 93 3 3 3 4/101/104
  KEY_NUMPAD_2        ,//5A Keypad 2 and Down Arrow Sel 98 3 3 3 4/101/104
  KEY_NUMPAD_3        ,//5B Keypad 3 and PageDn Sel 103 3 3 3 4/101/104
  KEY_NUMPAD_4        ,//5C Keypad 4 and Left Arrow Sel 92 3 3 3 4/101/104
  KEY_NUMPAD_5        ,//5D Keypad 5 Sel 97 3 3 3 4/101/104
  KEY_NUMPAD_6        ,//5E Keypad 6 and Right Arrow Sel 102 3 3 3 4/101/104
  KEY_NUMPAD_7        ,//5F Keypad 7 and Home Sel 91 3 3 3 4/101/104
  KEY_NUMPAD_8        ,//60 Keypad 8 and Up Arrow Sel 96 3 3 3 4/101/104
  KEY_NUMPAD_9        ,//61 Keypad 9 and PageUp Sel 101 3 3 3 4/101/104
  KEY_NUMPAD_0        ,//62 Keypad 0 and Insert Sel 99 3 3 3 4/101/104
  KEY_NUMPAD_DOT       //63 Keypad . and Delete Sel 104 3 3 3 4/101/104
  };



  int ps2_shift = 0;
  int ps2_ctrl = 0;
  int ps2_alt = 0;
  int usbLastKeyA = 0;
  int usbLastKeyB = 0;


  int getKey(int hid_value){
    IOWR(HID, 0, 0);

    int head  = (hid_value>>24) & 0xFF;
    int data2 = (hid_value>>16) & 0xFF;
    int data1 = (hid_value>> 8) & 0xFF;
    int data0 = (hid_value    ) & 0xFF;

    if(head == 0x81){//ps2 mouse
    }else if(head == 0x82){//ps2 keyboard
      if(data0 == KEY_SHIFTL || data0 == KEY_SHIFTR){
        ps2_shift = 1;
      }
      else if(data0 == 0xF0 && (data1 == KEY_SHIFTL || data1 == KEY_SHIFTR)){
        ps2_shift = 0;
      }else{
        if(data0 != 0xF0){
          int key;
          if(data0 == 0xE0){
            key = data1|0x80;
          }else{
            key = data0;
          }
          return (ps2_shift<<8) | key;
        }
      }
    }else if(head == 0x83){//usb keyboard
      int CSA = data2;
      int shift = 0;
      if((CSA & (1<<1)) || (CSA & (1<<5))){
        shift = 1;
      }
      //00 01 01 00 00 04 00 00 00 00 00,03
      //00 01 01 00 00 16 04 00 00 00 00,03
      //00 01 01 00 00 07 16 04 00 00 00,03
      int keyA = data0;
      int keyB = data1;
      int key = 0;
      if(keyA && keyA!=usbLastKeyA && keyA!=usbLastKeyB){
        key = keyA;
      }
      if(keyB && keyB!=usbLastKeyA && keyB!=usbLastKeyB){
        key = keyB;
      }
      usbLastKeyA = keyA;
      usbLastKeyB = keyB;
      if(key){
        return (shift<<8) | usb2ps2[key];
      }
    }else if(head == 0x84){//usb mouse
    }
    return 0;
  }

  int getchar(int key){
    int val;
    if(key & 0x0FF00){
      val = key2char[((key&0xFF) << 1)+1];
    }else{
      val = key2char[((key&0xFF) << 1)];
    }
    return val;
  }

  static void putcWinCore(int x, int y, int chr, int color){
    int* p = char_table+chr*4;
    int fg = color >> 16;
    int bg = color & 0xFFFF;
    IOWR(VGA_BLT, BLT_S_DESTX, x);
    if(! (x < 512 && x > (512 - 8))){
      IOWR(VGA_BLT, BLT_S_SETVAL, color);
      IOWR(VGA_BLT, BLT_S_WIDTH_HEIGHT, 8); // w
      IOWR(VGA_BLT, BLT_S_WIDTH_HEIGHT, 4); // h
      for(int j=0;j<16;j+=4){
        int calc_y = (y + j);
        IOWR(VGA_BLT, BLT_S_PATTERN, *p++);
        IOWR(VGA_BLT, BLT_M_DESTY_MEMSET_REQ, calc_y);
      }
    }else{
      IOWR(VGA_BLT, BLT_M_RST_FIFO, 0);
      IOWR(VGA_BLT, BLT_S_WIDTH_HEIGHT, 8);
      IOWR(VGA_BLT, BLT_S_WIDTH_HEIGHT, 16);
      for(int b=0;b<16;b+=4){
        int pat = *p++;
        for(int c=0;c<4;c++){
          for(int a=0;a<8;a++){
            IOWR(VGA_BLT, BLT_M_WRITE_DATA_YY, (pat&1)?fg:bg);
            pat = pat >> 1;
          }
        }
      }
      IOWR(VGA_BLT, BLT_M_DESTY_BUFWRI_REQ, y);
    }
  }

  static void putcUWinCore(int x, int y, int u, int color){

    char* map0 = (char*)u2gb;
    short* map1 = (short*)(((int)u2gb)+256);
    int tmp = map0[(u >> 8) & 0xFF];
    int pos = (tmp << 8) + (u & 0xFF);
    int gb = map1[pos];

    int tmp1 = gb&0xFF;
    int tmp2 = (gb>>8)&0xFF;
    int i = tmp1 - 0xA0;
    int j = tmp2 - 0xA0;
    int chr = 94 * (i - 1) + (j - 1);

    int* p = gb_char_table+chr*8;

    int fg = color >> 16;
    int bg = color & 0xFFFF;
    IOWR(VGA_BLT, BLT_S_DESTX, x);
    if(! (x < 512 && x > (512 - 16))){
      IOWR(VGA_BLT, BLT_S_SETVAL, color);
      IOWR(VGA_BLT, BLT_S_WIDTH_HEIGHT, 16); // w
      IOWR(VGA_BLT, BLT_S_WIDTH_HEIGHT, 2); // h
      for(j=0;j<16;j+=2){
        int calc_y = (y + j);
        IOWR(VGA_BLT, BLT_S_PATTERN, *p++);
        IOWR(VGA_BLT, BLT_M_DESTY_MEMSET_REQ, calc_y);
      }
    }else{
      IOWR(VGA_BLT, BLT_M_RST_FIFO, 0);
      IOWR(VGA_BLT, BLT_S_WIDTH_HEIGHT, 16);
      IOWR(VGA_BLT, BLT_S_WIDTH_HEIGHT, 16);
      for(int b=0;b<16;b+=2){
        int pat = *p++;
        for(int c=0;c<2;c++){
          for(int a=0;a<16;a++){
            IOWR(VGA_BLT, BLT_M_WRITE_DATA_YY, (pat&1)?fg:bg);
            pat = pat >> 1;
          }
        }
      }
      IOWR(VGA_BLT, BLT_M_DESTY_BUFWRI_REQ, y);
    }
  }

  static unsigned int utf8_to_unicode(char* str, int* len){
    unsigned char c = str[0];
    if (c < 0x80){
      *len=1;
      return c;
    }else if ((c & 0xE0) == 0xC0){
      // 2字节
      unsigned int val = ((c & 0x1F) << 6) | (str[1] & 0x3F);
      *len=2;
      return val;
    }else if ((c & 0xF0) == 0xE0){
      // 3字节
      unsigned int val =  ((c & 0x0F) << 12) | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F);
      *len=3;
      return val;
    }
    *len=1;
    return 0; // 错误字节
  }

  static ssize_t writeWin(void* cookie, const char *buf, size_t size){
    Window* win = (Window*)cookie;
    int idx = 0;
    char* str = (char*)buf;
    int* x = &(win->printX);
    int* y = &(win->printY);
    int left = win->printBaseX;
    int top = win->printBaseY;
    int right = left + win->printWidth;
    int bottom = top + win->printHeight;
    int color = win->printColor;
    while(str<(buf + size)){
      int len;
      unsigned int u = utf8_to_unicode(str, &len);
      str+=len;

      
      IOWR(VGA_BLT, BLT_M_RST_FIFO, 0);
      if(u<0x80){

        if(u == 0x0D || u == 0x0A){
        // }else if(u == 0x08){//,0x08,//#define KEY_BKSP            0x66  0000 1000 010 8 0x08 BS (backspace) ??
        //   if(*x>0){
        //     *x-=8;
        //     IOWR(VGA_BLT, BLT_S_DESTX, *x + win->abs_pos_x);
        //     IOWR(VGA_BLT, BLT_S_PATTERN, 0);
        //     for(int j=0;j<16;j+=4){
        //       void* addr;
        //       int calc_y = (*y + j);
        //       //paint_pattern(*x + win->abs_pos_x, calc_y + win->abs_pos_y, 8, 4, color, 0);
        //       IOWR(VGA_BLT, BLT_M_DESTY_MEMSET_REQ, calc_y + win->abs_pos_y);
        //     }
        //   }
        }else{
          putcWinCore(*x + win->abs_pos_x, *y + win->abs_pos_y, u, color);
          *x+=8;
        }
        if(*x>=right || (u == 0x0A)){
          *x=left;
          *y+=16;
          if(*y>=bottom){
            *y=top;
          }
          paint_pattern(left + win->abs_pos_x, *y + win->abs_pos_y, right-left, 16, color, 0);
        }

      }else{

        putcUWinCore(*x + win->abs_pos_x, *y + win->abs_pos_y, u, color);

        *x+=16;
        if(*x>=right){
          *x=left;
          *y+=16;
          if(*y>=bottom){
            *y=top;
          }
          paint_pattern(left + win->abs_pos_x, *y + win->abs_pos_y, right-left, 16, color, 0);
        }

      }
    }
    return size;
  }

`;

const intField = (Cls, cls, field) => {
  return String.raw/* cpp */`
    static JSValue js_${cls}_get_${field}(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
        ${Cls} *p = (${Cls}*)JS_GetOpaque(this_val);
        if(p){return JS_NewInt32(ctx, p->${field});}
    }
    static JSValue js_${cls}_set_${field}(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
      //printf("js_${cls}_set_${field}\n");
      ${Cls} *p = (${Cls}*)JS_GetOpaque(this_val);
      if(p){
        JS_ToInt32(ctx, &(p->${field}), argv[0]);
        //printf("p->${field}:%d\n", p->${field});
      }
      return JS_UNDEFINED;
    }
  `;
};

const setEvent = (Cls, cls, event) => {
  return String.raw/* cpp */`
static JSValue js_${cls}_set_${event}(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
    ${Cls} *p = (${Cls}*)JS_GetOpaque(this_val);
    if(p){p->${event} = JS_DupValue(ctx, argv[0]);}
    return JS_UNDEFINED;
}
  `;
}

const regFieldGetSet = (cls, proto, field) => {
  return String.raw/* cpp */`
    JS_DefinePropertyGetSet(
          ctx, ${proto},
          JS_NewAtom(ctx, "${field}"),
          JS_NewCFunction(ctx, js_${cls}_get_${field}, "${field}", 0),
          JS_NewCFunction(ctx, js_${cls}_set_${field}, "${field}", 1),
            JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE);
  `;
};

const regEvent = (cls, proto, event) => {
  return String.raw/* cpp */`
    JS_DefinePropertyGetSet(ctx, ${proto}, JS_NewAtom(ctx, "${event}"), JS_UNDEFINED, JS_NewCFunction(ctx, js_${cls}_set_${event}, "${event}", 1), JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE);
  `;
};

module.exports = { def, base, intField, setEvent, regFieldGetSet, regEvent };